/*
 * @Author: wz
 * @Date: 2020-12-02 15:57:26
 * @LastEditors: wz
 * @LastEditTime: 2020-12-05 11:49:00
 * @Description: mock 数据
 */
const chokidar = require('chokidar')
const bodyParser = require('body-parser')
const chalk = require('chalk')
const path = require('path')
const { mock } = require('mockjs')
const mockDir = path.join(process.cwd(), 'mock')
const { handleMockArray } = require('./utils')

let baseURL = ''
/**
 * @description: 注册路由
 * @param {*} app
 * @return {*}
 */
const registerRoutes = app => {
    let mockLastIndex
    const mocks = []
    const mockArray = handleMockArray()
    mockArray.forEach(item => {
        const obj = require(item)
        mocks.push(...obj)
    })
    const mocksForServer = mocks.map(route => {
        return responseFake(route.url, route.type, route.response)
    })

    for (const mock of mocksForServer) {
        app[mock.type](mock.url, mock.response)
        mockLastIndex = app._router.stack.length
    }
    const mockRoutesLength = Object.keys(mocksForServer).length
    return {
        mockRoutesLength: mockRoutesLength,
        mockStartIndex: mockLastIndex - mockRoutesLength,
    }
}
/**
 * @description:  返回数据
 * @param {*} url
 * @param {*} type
 * @param {*} respond
 * @return {*}
 */
const responseFake = (url, type, respond) => {
    return {
        url: new RegExp(`${baseURL}${url}`),
        type: type || 'get',
        response(req, res) {
            res.status(200)
            if (JSON.stringify(req.body) !== '{}') {
                console.log(chalk.green(`> 请求地址：${req.path}`))
                console.log(chalk.green(`> 请求参数：${JSON.stringify(req.body)}\n`))
            } else {
                console.log(chalk.green(`> 请求地址：${req.path}\n`))
            }
            res.json(mock(respond instanceof Function ? respond(req, res) : respond))
        },
    }
}

module.exports = app => {
    app.use(bodyParser.json())
    app.use(
        bodyParser.urlencoded({
            extended: true,
        })
    )
    const mockRoutes = registerRoutes(app)
    let mockRoutesLength = mockRoutes.mockRoutesLength
    let mockStartIndex = mockRoutes.mockStartIndex
    // 监听 mock 文件修改f
    chokidar
        .watch(mockDir, {
            ignoreInitial: true,
        })
        .on('all', event => {
            if (event === 'change' || event === 'add') {
                try {
                    app._router.stack.splice(mockStartIndex, mockRoutesLength)

                    Object.keys(require.cache).forEach(item => {
                        if (item.includes(mockDir)) {
                            delete require.cache[require.resolve(item)]
                        }
                    })
                    const mockRoutes = registerRoutes(app)
                    mockRoutesLength = mockRoutes.mockRoutesLength
                    mockStartIndex = mockRoutes.mockStartIndex
                } catch (error) {
                    console.log(chalk.red(error))
                }
            }
        })
}
